Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

JOIN SUM и DiSTINCT (yprokopets)
Author Message
yprokopets
Заглянувший



Joined: 05 Sep 2008
Posts: 5
Карма: 0
   поощрить/наказать

Location: Ukraine

PostPosted: Mon Dec 01, 2008 6:51 pm (написано за 7 минут 28 секунд)
   Post subject: JOIN SUM и DiSTINCT
Reply with quote

Есть 2 таблицы.
Одна з юзверами

users
-----------------
id
name

Вторая с их часами переработки/недоработки

hours
----------------
id
userId int, FK
type enum('overtime', 'absence')
date date
hours int

Нужно вытащить сумму переработаных и недоработаних часов юзверами за месяц

Пробую так
Code (SQL): скопировать код в буфер обмена
SELECT
        u.name,
        SUM(DISTINCT ove.hours),
        SUM(DISTINCT abs.hours),
FROM
        users u
LEFT JOIN hours ove ON (ove.userId = u.id AND ove.type = 'overtime')
LEFT JOIN hours abs ON (abs.userId = u.id AND abs.type = 'absence')
GROUP BY u.id
Но при этом DISTINCT откидает записи с одинокавым кол-вом часом, без него же получаю тоже неверные значения.

Как быть?
Back to top
View user's profile Send private message
Никитин Максим
Заглянувший



Joined: 13 Jan 2009
Posts: 7
Карма: 1
   поощрить/наказать


PostPosted: Tue Jan 13, 2009 6:13 pm (спустя 1 месяц 11 дней 23 часа 21 минуту; написано за 4 минуты 39 секунд)
   Post subject:
Reply with quote

Быть очень просто - понять, что вернет конструкция
Code (SQL): скопировать код в буфер обмена
FROM
users u
LEFT JOIN hours ove ON (ove.userId = u.id AND ove.type = 'overtime')
LEFT JOIN hours abs ON (abs.userId = u.id AND abs.type = 'absence')
Если в уме сложно прикинуть, сделайте запрос
Code (SQL): скопировать код в буфер обмена
SELECT
*
FROM
users u
LEFT JOIN hours ove ON (ove.userId = u.id AND ove.type = 'overtime')
LEFT JOIN hours abs ON (abs.userId = u.id AND abs.type = 'absence')
И обратите внимание на дублирование строк из таблицы hours. При выполнении запроса сначала строится объединение таблиц из FROM. Из-за этого и происходит дублирование.
Исходя из этого, получается, что часть таблицы с 'overtime' ничего не должна "знать" о части с 'absence'. Поэтому убираем их из объединения.
Code (SQL): скопировать код в буфер обмена
SELECT u.name, (

SELECT SUM( ove.hours )
FROM hours ove
WHERE ove.userId = u.id
AND ove.type = 'overtime'
) AS ove_sum, (

SELECT SUM( abs.hours )
FROM hours abs
WHERE abs.userId = u.id
AND abs.type = 'absence'
) AS abs_sum
FROM users u


Last edited by Никитин Максим on Wed Jan 14, 2009 11:08 am; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail
bæv
Модератор «Дзена»



Joined: 27 Aug 2003
Posts: 7275
Карма: 9985
   поощрить/наказать


PostPosted: Tue Jan 13, 2009 9:53 pm (спустя 3 часа 40 минут; написано за 56 секунд)
   Post subject:
Reply with quote


М

Никитин Максим, на форуме принято общение «на Вы».
forum.dklab.ru/about/todo/PravilaEtogoForuma-ProchitayteObyazatelno.html
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML